package org.jiamandan.com.strategy.listener;

import lombok.extern.slf4j.Slf4j;
import org.jiamandan.com.dto.DXBasicDto;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class DXPunchTheCardService {

    /**
     * 下发刷卡结果 ToDo 卡号需要修改
     */
    public Boolean parse(long cardNo, DXBasicDto dto, String punchCardId, String gunNo) {
        //刷卡处理
        return null;
    }
        /*DistributedRedisLock distributedRedisLock = SpringUtil.getBean(DistributedRedisLock.class);
        String value = Func.toStr(System.currentTimeMillis());
        String cardStr = String.format("%010d", cardNo);
        Boolean lockR = distributedRedisLock.tryLock(cardStr, value, 5, TimeUnit.SECONDS);
        try {
            IMemberCardService iMemberCardService = SpringUtil.getBean(IMemberCardService.class);
            IRechargePileService iRechargePileService = SpringUtil.getBean(IRechargePileService.class);
            IMemberService iMemberService = SpringUtil.getBean(IMemberService.class);
            IRechargeGunService iRechargeGunService = SpringUtil.getBean(IRechargeGunService.class);
            MemberCard card = iMemberCardService.getByCardNo(cardStr);
            //支持两种卡片写入方式
            if (card == null || card.getMemberId() == null) {
                //String cardNoBt = StringUtils.leftPad(String.valueOf(cardNo), 10, "0");
                long cardNoBt = Long.parseLong(StringUtils.substring(dto.getData(), 2, 10), 16);
                card = iMemberCardService.getByCardNo(Func.toStr(cardNoBt));
            }
            RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
            //查询刷卡状态
            String cardObject = (String) redisUtil.hget(CacheNames.UDP_CARD, dto.getDeviceNo());
            if (null != cardObject) {
                //刷卡流水存在
                if (cardObject.equals(punchCardId)) {
                    return false;
                }
                //todo->刷卡超时
            }
            redisUtil.hset(CacheNames.UDP_CARD, dto.getDeviceNo(), punchCardId);
            if (lockR) {
                if (card.getIsBind() == BizConstant.IsBind.unbind) {    //卡未绑定
                    issue02(dto.getDeviceNo(), cardStr, "05", 0, punchCardId, gunNo);
                    return false;
                }
                if (card.getIsBind() == BizConstant.IsBind.freeze) {    //卡冻结
                    issue02(dto.getDeviceNo(), cardStr, "05", 0, punchCardId, gunNo);
                    return false;
                }
                if (card.getIsBind() == BizConstant.IsBind.loss) {    //卡已经挂失
                    issue02(dto.getDeviceNo(), cardStr, "03", 0, punchCardId, gunNo);
                    return false;
                }
                RechargePile pile = iRechargePileService.getOne(Wrappers.<RechargePile>query().lambda().eq(RechargePile::getPileNo, dto.getDeviceNo()));
                //该设备还未注册
                if (pile == null) {
                    issue02(dto.getDeviceNo(), cardStr, "06", 0, punchCardId, gunNo);
                    return false;
                }
                if (card == null || card.getMemberId() == null) {
                    //01未注册（语音“未注册卡”)   未添加卡号或未绑定微信用户
                    issue02(dto.getDeviceNo(), cardStr, "05", 0, punchCardId, gunNo);
                    return false;
                }
                if (card.getIsBind() != BizConstant.IsBind.bind) {
                    //卡丢失
                    issue02(dto.getDeviceNo(), cardStr, "05", 0, punchCardId, gunNo);
                    return false;
                }
                Member member = iMemberService.getById(card.getMemberId());
                Integer balance = member.getBalance().divide(BigDecimal.valueOf(100L)).intValue();
                if (member == null) {
                    //01未注册（语音“未注册卡”)   未添加卡号或未绑定微信用户
                    issue02(dto.getDeviceNo(), cardStr, "05", balance, punchCardId, gunNo);
                    return false;
                }
                if (member.getStatus() == 0) {
                    issue02(dto.getDeviceNo(), cardStr, "05", balance, punchCardId, gunNo);
                    return false;
                }
                //查询余额
                if (member.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
                    //余额不足
                    log.info("卡号【" + cardStr + "】余额查询：" + balance);
                    issue02(dto.getDeviceNo(), cardStr, "00", balance, punchCardId, gunNo);
                    return false;
                }
                RechargeGun gun = iRechargeGunService.getOne(Wrappers.<RechargeGun>query().lambda().eq(RechargeGun::getPileNo, dto.getDeviceNo()).eq(RechargeGun::getGunNo, gunNo));
                if (gun.getWorkStatus() == BizConstant.WorkStatus.CHARGING) {
                    //插座被占用
                    issue02(dto.getDeviceNo(), cardStr, "01", 0, punchCardId, gunNo);
                    return false;
                }
                if (gun.getWorkStatus() == BizConstant.WorkStatus.FAULT) {
                    //插座坏了
                    issue02(dto.getDeviceNo(), cardStr, "06", 0, punchCardId, gunNo);
                    return false;
                }
                //1.创建订单，2.开启充电
                if (gun.getWorkStatus() == BizConstant.WorkStatus.FREE) {
                    OrderCharge order = createOrder(gun, member, dto, cardStr, balance, punchCardId, gunNo);
                    if (order != null) {
                        ///减掉余额
                        if (member.getBalance().compareTo(order.getPayAmt()) >= 0) {
                            member.setBalance(member.getBalance().subtract(order.getPayAmt()));
                        } else {
                            member.setBalance(BigDecimal.ZERO);
                            member.setPresentAmt(member.getPresentAmt().subtract(order.getPresentAmtPay()));
                        }
                        order.setPayTime(DateUtil.now());
                        order.setPayType(BizConstant.payType.BANLANCE);
                        order.setOrderStatus(BizConstant.OrderStatus.PAID);
                        order.setStartBalance(order.getPayAmt());
                        order.setStartTime(DateUtil.formatDateTime(DateUtil.now()));
                        order.setRetryTimes(0);
                        iMemberService.updateById(member);
                        //添加流水
                        IMemberBillsService iMemberBillsService = SpringUtil.getBean(IMemberBillsService.class);
                        iMemberBillsService.createMemberBills(member, order.getOrderNo(), order.getPayAmt(), BillConstant.Bill.BALANCE_CHARGE_PAY);
                        //下发充电
                        Boolean result = iRechargePileService.issueCharge(gun, order, order.getPayAmt());
                        if (!result) {
                            order.setRemark("下发充电失败");
                            order.setOrderStatus(BizConstant.OrderStatus.CHARGING_FAILURE);
//                                  throw new Exception("下发充电失败");
                        }
                        IOrderChargeService iOrderChargeService = SpringUtil.getBean(IOrderChargeService.class);
                        boolean resultStatus = iOrderChargeService.updateById(order);
                        log.info("修改刷卡充电状态={},订单号={},卡号={}", resultStatus, order.getOrderNo(), cardNo);
                        UpdateWrapper<OrderCharge> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.set("pay_time", order.getPayTime());
                        updateWrapper.set("pay_type", order.getPayType());
                        updateWrapper.set("order_status", order.getOrderStatus());
                        updateWrapper.set("start_balance", order.getStartBalance());
                        updateWrapper.set("start_time", order.getStartTime());
                        updateWrapper.set("retry_times", order.getRetryTimes());
                        //updateWrapper.lambda().eq(OrderCharge::getCreateTime,order.getCreateTime());
                        updateWrapper.eq("id", order.getId());
                        updateWrapper.eq("create_time", order.getCreateTime());
                        return true;
                        //iOrderChargeService.update(updateWrapper);
                        //  boolean update = iOrderChargeService.update(updateWrapper);
                        //iOrderChargeService.update(order, Wrappers.<OrderCharge>lambdaUpdate().eq(OrderCharge::getOrderNo, order.getOrderNo()));
                    }
                }
            }
        } catch (Exception e) {
            log.error("下单充电失败:" + e.getMessage());
            throw new RuntimeException(e.getMessage());
        } finally {
            distributedRedisLock.unlock(Func.toStr(cardNo), value);
        }
        return false;
    }

    private void issue02(String deviceNo, String cardStr, String cardStatus, int balance, String punchCardId, String gunNo) {
        String cardNoStr = StringUtils.rightPad(cardStr, 8, "0");
        String balanceStr = StringUtils.rightPad(Long.toHexString(balance), 8, "0");
        StringBuilder builder = new StringBuilder();
        builder.append(punchCardId)
                .append(cardNoStr)        //卡号
                .append(cardStatus)
                .append(balanceStr);
        DXBasicDto dto = new DXBasicDto();
        dto.setReserved("000000");
        dto.setProtocol("01");
        dto.setDeviceNo(deviceNo);
        UdpServerHandler.sendMessage(builder.toString(), dto, gunNo, DXConstant.Cmd.CMD_A80);
    }

    private OrderCharge createOrder(RechargeGun gun, Member member, DXBasicDto dto, String cardStr, Integer balance, String punchCardId, String gunNo) {
        if (gun == null) {
            log.error("刷卡端口故障：gun==null");
            //端口故障
            issue02(dto.getDeviceNo(), cardStr, "06", balance, punchCardId, gunNo);
            return null;
        }
        if (gun.getOnlineStatus() != BizConstant.OnOffLine.ONLINE) {
            log.error("刷卡端口故障：离线");
            //端口故障
            issue02(dto.getDeviceNo(), cardStr, "02", balance, punchCardId, gunNo);
            return null;
        }
        if (gun.getModelId() == null) {
            log.error("刷卡端口故障：计费模型id==null");
            //端口故障
            issue02(dto.getDeviceNo(), cardStr, "02", balance, punchCardId, gunNo);
            return null;
        }
        ISiteService iSiteService = SpringUtil.getBean(ISiteService.class);
        Site site = iSiteService.getById(gun.getSiteId());
        if (site == null) {
            log.error("刷卡端口故障：站点为空");
            //端口故障
            issue02(dto.getDeviceNo(), cardStr, "02", balance, punchCardId, gunNo);
            return null;
        }
        if (site.getStatus() != 5) {
            log.error("刷卡端口故障：站点状态不是正常使用");
            //端口故障
            issue02(dto.getDeviceNo(), cardStr, "02", balance, punchCardId, gunNo);
            return null;
        }
        long id = IdentityIdUtil.getFlowIdInstance().nextId();
        OrderCharge orderCharge = new OrderCharge();
        orderCharge.setOrderNo(Func.toStr(id));
        orderCharge.setMemberId(member.getId());
        orderCharge.setMemberName(member.getNickName());
        orderCharge.setPhone(member.getPhoneNo());
        orderCharge.setOrgCode(gun.getOrgCode());
        orderCharge.setTenantId(gun.getTenantId());
        orderCharge.setRealPower(BigDecimal.ZERO);
        orderCharge.setChargeAmt(BigDecimal.ZERO);
        orderCharge.setPayType(BizConstant.payType.BANLANCE);
        orderCharge.setTotalServiceCost(BigDecimal.ZERO);
        orderCharge.setSumChargeTime("00:00:00");
        orderCharge.setDiscountAmt(BigDecimal.ZERO);
        //5元充电
        BigDecimal fivePrice = new BigDecimal("5");
        if ((member.getBalance().add(member.getPresentAmt())).compareTo(fivePrice) >= 0) {
            orderCharge.setPayAmt(fivePrice);
            if (member.getBalance().compareTo(fivePrice) >= 0) {
                orderCharge.setBalancePay(fivePrice);
                orderCharge.setPresentAmtPay(BigDecimal.ZERO);
            } else {
                orderCharge.setBalancePay(member.getBalance());
                orderCharge.setPresentAmtPay(fivePrice.subtract(member.getBalance()));
            }
        } else {
            orderCharge.setPayAmt(member.getBalance().add(member.getPresentAmt()));
            orderCharge.setBalancePay(member.getBalance());
            orderCharge.setPresentAmtPay(member.getPresentAmt());
        }
        orderCharge.setSeizeSeatFee(BigDecimal.ZERO);
        orderCharge.setRefundAmt(BigDecimal.ZERO);
        orderCharge.setOrderAmt(BigDecimal.ZERO);
        orderCharge.setMaxChargePower(BigDecimal.ZERO);
        orderCharge.setChargeDuration(0);
        orderCharge.setProfit(BizConstant.ProfitStatus.PROFIT_NO);
        orderCharge.setSource(BizConstant.Source.CARD);
        orderCharge.setSiteId(site.getId());
        orderCharge.setChargePileId(gun.getPileId());
        orderCharge.setChargePileNo(gun.getPileNo());
        orderCharge.setChargeGunId(gun.getId());
        orderCharge.setChargeGunNo(gun.getGunNo());
        orderCharge.setCardNo(cardStr);
        orderCharge.setTotalElectric(BigDecimal.ZERO);
        if (site.getAgentId() != null) {
            orderCharge.setAgentId(site.getAgentId());
        }
        if (site.getMerchantId() != null) {
            orderCharge.setMerchantId(site.getMerchantId());
        }
        if (site.getSalesId() != null) {
            orderCharge.setSalesId(site.getSalesId());
        }
        orderCharge.setAgentCommission(Double.valueOf("0.0"));
        orderCharge.setMerchantCommission(Double.valueOf("0.0"));
        orderCharge.setSalesCommission(Double.valueOf("0.0"));
        orderCharge.setPayTime(DateUtil.now());
        orderCharge.setOrderStatus(BizConstant.OrderStatus.PAID);
        orderCharge.setCreateTime(DateUtil.now());
        IOrderChargeService iOrderChargeService = SpringUtil.getBean(IOrderChargeService.class);
        iOrderChargeService.saveOrUpdate(orderCharge);
        return orderCharge;
    }*/

}
